package com.powernode.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.constant.BusinessEnum;
import com.powernode.domain.MemberCollection;
import com.powernode.domain.Prod;
import com.powernode.ex.handler.BusinessException;
import com.powernode.feign.MemberProdFeign;
import com.powernode.mapper.MemberCollectionMapper;
import com.powernode.model.Result;
import com.powernode.service.MemberCollectionService;
import com.powernode.utils.AuthUtils;
import org.apache.commons.collections4.BagUtils;
import org.bouncycastle.mime.CanonicalOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MemberCollectionServiceImpl extends ServiceImpl<MemberCollectionMapper, MemberCollection> implements MemberCollectionService {

    @Autowired
    private MemberCollectionMapper memberCollectionMapper;

    @Autowired
    MemberProdFeign memberProdFeign;

    /**
     * 重写queryMemberCollectionProdCount方法，用于查询当前用户收藏的商品数量
     *
     * @return 当前用户收藏的商品数量
     */
    @Override
    public Long queryMemberCollectionProdCount() {
        // 获取当前用户的openId
        String openId = AuthUtils.getMemberOpenId();

        // 使用LambdaQueryWrapper构建查询条件，查询当前用户收藏的商品数量
        // eq方法用于设置等值条件，MemberCollection::getOpenId表示获取MemberCollection对象的openId属性
        return memberCollectionMapper.selectCount(new LambdaQueryWrapper<MemberCollection>().eq(MemberCollection::getOpenId, openId));
    }

    /**
     * 根据用户OpenID查询用户收藏的商品分页信息
     *
     * @param memberOpenId 用户OpenID
     * @param current      当前页码
     * @param size         每页数量
     * @return 商品分页对象
     * @throws BusinessException 远程调用失败时抛出
     */
    @Override
    public Page<Prod> queryMemberCollectionProdPageByOpenId(String memberOpenId, Long current, Long size) {
        // 初始化商品分页对象
        Page<Prod> prodPage = new Page<>(current, size);
        // 初始化会员收藏分页对象
        Page<MemberCollection> memberCollectionPage = new Page<>(current, size);
        // 查询会员收藏信息，并按创建时间降序排列
        memberCollectionPage = memberCollectionMapper.selectPage(memberCollectionPage, new LambdaQueryWrapper<MemberCollection>().eq(MemberCollection::getOpenId, memberOpenId).orderByDesc(MemberCollection::getCreateTime));
        // 获取会员收藏记录列表
        List<MemberCollection> memberCollectionList = memberCollectionPage.getRecords();
        // 如果收藏记录为空，则直接返回空的 商品分页对象
        if (CollectionUtils.isEmpty(memberCollectionList) || memberCollectionList.size() == 0) {
            return prodPage;
        }
        // 获取所有收藏商品的ID列表
        List<Long> prodIdList = memberCollectionList.stream().map(MemberCollection::getProdId).collect(Collectors.toList());
        // 远程调用会员商品服务获取商品信息列表
        Result<List<Prod>> result = memberProdFeign.getProdListByIds(prodIdList);
        // 如果远程调用失败，抛出业务异常
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new BusinessException("远程调用：根据商品ID集合查询商品对象集合失败");
        }
        // 获取商品信息列表
        List<Prod> prodList = result.getData();
        // 将商品信息列表设置到商品分页对象中
        prodPage.setRecords(prodList);
        // 设置商品分页对象的总记录数、总页数
        prodPage.setTotal(memberCollectionPage.getTotal());
        prodPage.setPages(memberCollectionPage.getPages());
        // 返回商品分页对象
        return prodPage;
    }

    /**
     * 添加或取消会员收藏
     *
     * @param memberOpenId 会员的OpenId
     * @param prodId       商品ID
     * @return 如果添加成功返回true，如果取消成功返回true，否则返回false
     */
    @Override
    public Boolean addOrCancelMemberCollection(String memberOpenId, Long prodId) {
        MemberCollection memberCollection = memberCollectionMapper.selectOne(new LambdaQueryWrapper<MemberCollection>().eq(MemberCollection::getOpenId, memberOpenId).eq(MemberCollection::getProdId, prodId));
        if (ObjectUtil.isNull(memberCollection)) {
            memberCollection = new MemberCollection();
            memberCollection.setCreateTime(new Date());
            memberCollection.setOpenId(memberOpenId);
            memberCollection.setProdId(prodId);
            return memberCollectionMapper.insert(memberCollection) > 0;
        }
        return memberCollectionMapper.deleteById(memberCollection.getId()) > 0;
    }
}
